package jwf.http;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

import jwf.fcgi.FCGXRequest;
import jwf.http.Http.HttpVerb;

import com.fastcgi.FCGIRequest;

public class Request {

    private static final String HTTP = "HTTP_";
    private static final String EMPTY_SRING = "";

    private Map<String, String> header;
    private String queryString;
    private Map<String, String> query;
    private Map<String, String> form;
    private HttpVerb method;
    private String requestUri;

    private Cookie cookie;

    private FCGXRequest fcgxReq;

    public Request(FCGXRequest fcgxReq) {
	this.fcgxReq = fcgxReq;
	header = new HashMap<String, String>();
	method = HttpVerb.HV_INVALID;
	queryString = "";
	query = new HashMap<String, String>();
	form = new HashMap<String, String>();
	requestUri = "";
	parseHeader(this.fcgxReq.getParams());
	cookie = new Cookie(header.get("COOKIE"));
    }

    private void parseHeader(Map<String, String> params) {
	Set<Entry<String, String>> entrySet = params.entrySet();
	for (Entry<String, String> entry : entrySet) {
	    String key = entry.getKey();
	    String value = entry.getValue();
	    if (key.startsWith(HTTP)) {
		header.put(key.substring(HTTP.length(), key.length()), value);
	    } else if (key.equalsIgnoreCase("QUERY_STRING")) {
		queryString = value;
		query.putAll(parseQuery(queryString));
		header.put("QUERY_STRING", value);
	    } else if (key.equals("REQUEST_METHOD")) {
		if (value.equals("GET")) {
		    method = HttpVerb.HV_GET;
		} else if (value.equals("POST")) {
		    method = HttpVerb.HV_POST;
		    for (String s : fcgxReq.getStdin()) {
			form.putAll(parseQuery(s));
		    }
		}
		header.put("REQUEST_METHOD", value);
	    } else if (key.equals("REQUEST_URI")) {
		requestUri = value;
		header.put("REQUEST_URI", value);
	    } else {
		header.put(key, value);
	    }
	}
    }

    public Cookie getCookie() {
	return cookie;
    }

    public HttpVerb getMethod() {
	return method;
    }

    public String host() {
	return header.get("HOST");
    }

    public String uri() {
	return requestUri;
    }

    public String url() {
	return host() + uri();
    }

    public String query(String key) {
	String v = header.get(key);
	if (v != null) {
	    return v;
	}
	return EMPTY_SRING;
    }

    public int query(String key, int defaultValue) {
	String v = header.get(key);
	if (v != null) {
	    try {
		return Integer.parseInt(v);
	    } catch (Exception e) {

	    }
	}
	return defaultValue;
    }

    public String get(String key) {
	String v = query(key);
	if (EMPTY_SRING.equals(v)) {
	    return form(key);
	}
	return v;
    }

    public String form(String key) {
	String v = form.get(key);
	if (v != null) {
	    return v;
	}
	return EMPTY_SRING;
    }

    public Map<String, String> getHeader() {
	return header;
    }

    public String getQueryString() {
	return queryString;
    }

    private static Map<String, String> parseQuery(String str) {
	Map<String, String> map = new HashMap<String, String>();
	String[] equalArray = str.split("&");
	for (String equal : equalArray) {
	    int index = equal.indexOf("=");
	    if (index != -1) {
		String[] kv = equal.split("=");
		if (kv.length == 2) {
		    map.put(kv[0], kv[1]);
		}
		if (kv.length == 1) {
		    map.put(kv[0], EMPTY_SRING);
		}
	    }
	}
	return map;
    }
}
